home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
telecomm
/
sticpsrc.lzh
/
SOURCE.ARC
/
PATHNAME.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-12-16
|
4KB
|
134 lines
#include "global.h"
#include <ctype.h>
/* Given a working directory and an arbitrary pathname, resolve them into
* an absolute pathname. Memory is allocated for the result, which
* the caller must free
*/
char *
pathname(cd,path)
char *cd; /* Current working directory */
char *path; /* Pathname argument */
{
register char *buf,*cp;
char *cdtmp,*pathtmp,*strcpy();
if(cd == NULLCHAR || path == NULLCHAR)
return NULLCHAR;
#if (defined(MSDOS) || defined(ATARI_ST))
/* Make temporary copies of cd and path
* with all \'s translated to /'s
*/
if ((pathtmp = malloc((unsigned)strlen(path)+1)) == NULLCHAR)
return NULLCHAR;
for (cp = path = strcpy(pathtmp,path); *cp != '\0'; cp++)
if (*cp == '\\')
*cp = '/';
if ((cdtmp = malloc((unsigned)strlen(cd)+1)) == NULLCHAR) {
free(pathtmp);
return NULLCHAR;
}
for (cp = cd = strcpy(cdtmp,cd); *cp != '\0'; cp++)
if (*cp == '\\')
*cp = '/';
#endif
/* Strip any leading white space on args */
while(*cd == ' ' || *cd == '\t')
cd++;
while(*path == ' ' || *path == '\t')
path++;
/* Allocate and initialize output buffer; user must free */
buf = malloc((unsigned)strlen(cd) + strlen(path) + 10); /* fudge factor */
if (buf == NULLCHAR)
goto nomem;
buf[0] = '\0';
/* Interpret path relative to cd only if it doesn't begin with "/" */
/* or "D:/" (support for drive names) */
if(path[0] == '/' && cd[1] == ':') {
buf[0] = cd[0]; /* start from root on current drv */
buf[1] = ':';
buf[2] = '\0';
}
if(path[0] != '/' &&
!(isalpha(path[0]) && path[1] == ':' && path[2] == '/'))
crunch(buf,cd);
crunch(buf,path);
/* Special case: null final path or drive only means the root directory */
if(buf[0] == '\0' ||
(isalpha(buf[0]) && buf[1] == ':' && buf[2] == '\0'))
strcat(buf,"/");
nomem:
#if (defined(MSDOS) || defined(ATARI_ST))
/* Translate all /'s back to \'s and free temp copies of args */
for (cp = buf; *cp != '\0'; cp++)
if (*cp == '/')
*cp = '\\';
free(cdtmp);
free(pathtmp);
#endif
return buf;
}
/* Process a path name string, starting with and adding to
* the existing buffer
*/
static
crunch(buf,path)
char *buf;
register char *path;
{
register char *cp;
if (isalpha(*path) && path[1] == ':'){ /* drive spec */
cp = buf; /* Re-write entire buffer */
*cp++ = *path++;
*cp++ = *path++;
*cp = '\0';
} else {
cp = buf + strlen(buf); /* Start write at end of current buffer */
}
/* Now start crunching the pathname argument */
for(;;){
/* Strip leading /'s; one will be written later */
while(*path == '/')
path++;
if(*path == '\0')
break; /* no more, all done */
/* Look for parent directory references, either at the end
* of the path or imbedded in it
*/
if(strcmp(path,"..") == 0 || strncmp(path,"../",3) == 0){
/* Hop up a level */
if((cp = rindex(buf,'/')) == NULLCHAR)
cp = buf; /* Don't back up beyond root */
*cp = '\0'; /* In case there's another .. */
path += 2; /* Skip ".." */
while(*path == '/') /* Skip one or more slashes */
path++;
/* Look for current directory references, either at the end
* of the path or imbedded in it
*/
} else if(strcmp(path,".") == 0 || strncmp(path,"./",2) == 0){
/* "no op" */
path++; /* Skip "." */
while(*path == '/') /* Skip one or more slashes */
path++;
} else {
/* Ordinary name, copy up to next '/' or end of path */
*cp++ = '/';
while(*path != '/' && *path != '\0')
*cp++ = *path++;
}
}
*cp++ = '\0';
}